﻿using Core;
using Core.Librarys;
using Core.Servicers.Interfaces;
using FileSC.Configs.StatusBar;
using FileSC.Win;
using FileSC.Win.api;
using FileSC.Win.hooks;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Threading;
using System.Xml.Linq;
using UI.ViewModels;

namespace UI.Servicers
{
    public class StatusBarIconServicer : IStatusBarIconServicer
    {
        //  状态栏图标
        private System.Windows.Forms.NotifyIcon _statusBarIcon;
        //  状态栏图标菜单
        private ContextMenu _contextMenu;

        internal readonly IThemeServicer _themeServicer;
        internal readonly MainViewModel _mainVM;
        internal readonly IAppConfig2 _appConfig;
        internal readonly IUIServicer _uIServicer;
        internal readonly IAppObserver _appObserver;
        internal MouseHook hook_mouse;
        internal MainWindow _mainWindow;
        public StatusBarIconServicer(
            IThemeServicer themeServicer_,
            IAppConfig2 appConfig_,
            MainViewModel mainVM_,
            IUIServicer uIServicer_,
            IAppObserver appObserver_
            )
        {
            _themeServicer = themeServicer_;
            _appConfig = appConfig_;
            _mainVM = mainVM_;
            _uIServicer = uIServicer_;
            _appObserver = appObserver_;
            hook_mouse = new MouseHook();
        }
        public void Init()
        {
            InitMenu();

            _statusBarIcon = new System.Windows.Forms.NotifyIcon();
            _statusBarIcon.Visible = true;
            _statusBarIcon.MouseClick += _statusBarIcon_MouseClick;
            _statusBarIcon.MouseDoubleClick += _statusBarIcon_MouseDoubleClick;

            SetIcon(IconType.Busy);

            WatchStateAsync();

            _themeServicer.OnThemeChanged += _themeServicer_OnThemeChanged;
            Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
            hook_mouse.MouseUpEvent += OnGlobalMouseUp;
            _appObserver.OnAppActiveChanged += _appObserver_OnAppActiveChanged;
        }

        private void OnGlobalMouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (_contextMenu.IsOpen) HideMenu();
        }

        private void Current_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            _statusBarIcon.Visible = false;
        }

        private void _themeServicer_OnThemeChanged(object sender, EventArgs e)
        {
            _contextMenu.UpdateDefaultStyle();
        }

        private void _appObserver_OnAppActiveChanged(object sender, Core.Event.AppActiveChangedEventArgs e)
        {
            if (e.Window.ClassName != "Shell_TrayWnd")
            {
                hook_mouse.UnHook();
                _appObserver.Stop();

                Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
                {
                    HideMenu();
                }));
            }
        }

        /// <summary>
        /// 初始化状态栏菜单
        /// </summary>
        private void InitMenu()
        {

            _contextMenu = new ContextMenu();
            var mainWindowMenuItem = new MenuItem();
            mainWindowMenuItem.Header = "主界面";
            mainWindowMenuItem.Click += MainWindowMenuItem_Click;
            var exitMenuItem = new MenuItem();
            exitMenuItem.Header = "退出";
            exitMenuItem.Click += ExitMenuItem_Click;

            _contextMenu.Items.Add(mainWindowMenuItem);
            _contextMenu.Items.Add(exitMenuItem);
            _contextMenu.Opened += _contextMenu_Opened;
            _contextMenu.Closed += _contextMenu_Closed;
        }

        private void _contextMenu_Opened(object sender, RoutedEventArgs e)
        {
            _contextMenu.UpdateLayout();
            ok = true;
            hook_mouse.SetHook();
            _appObserver.Start();
        }

        private void _contextMenu_Closed(object sender, RoutedEventArgs e)
        {
            hook_mouse.UnHook();
            _appObserver.Stop();
            ok = false;
            Win32Api.ReleaseWorkingSize();
        }

        /// <summary>
        /// 等待程序加载
        /// </summary>
        private async void WatchStateAsync()
        {
            await Task.Run(() =>
            {
                while (AppState.IsLoading)
                {
                    _statusBarIcon.Text = $"[{AppState.ProcessValue}%] FileSC [{AppState.ActionText}]";
                }
                _statusBarIcon.Text = "文件下载服务";
                SetIcon();
            });
        }

        /// <summary>
        /// 设置图标
        /// </summary>
        /// <param name="iconType_">图标样式</param>
        public void SetIcon(IconType iconType_ = IconType.Normal)
        {
            try
            {
                string iconName = "app";
                switch (iconType_)
                {
                    case IconType.Busy:
                        iconName += "-stop";
                        break;
                    case IconType.Download:
                        iconName += "-download";
                        break;
                    case IconType.Error:
                        iconName += "-error";
                        break;
                    case IconType.OK:
                        iconName += "-ok";
                        break;
                    case IconType.Run:
                        iconName += "run";
                        break;
                    case IconType.Stop:
                        iconName += "stop";
                        break;
                    case IconType.T1:
                        iconName += "-t1";
                        break;
                    case IconType.T2:
                        iconName += "-t2";
                        break;
                    case IconType.T3:
                        iconName += "-t3";
                        break;
                    default:
                        iconName += "-run";
                        break;
                }
                Stream iconStream = Application.GetResourceStream(new Uri($"pack://application:,,,/FileSC.UI;component/Resources/Icons/{iconName}.ico")).Stream;
                _statusBarIcon.Icon = new Icon(iconStream);
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
                Logger.Save(true);
            }
        }
        public void ShowMainWindow()
        {
            hook_mouse.UnHook(); //防止卡顿
            _appObserver.Stop();

            var config = _appConfig.GetConfig();
            if (config == null)
            {
                return;
            }

            if (_mainWindow == null || _mainWindow.IsWindowClosed)
            {
                _mainWindow = new MainWindow();
                _mainWindow.DataContext = _mainVM;
                _mainWindow.Loaded += _mainWindow_Loaded;
                _mainVM.LoadDefaultPage();
            }
            else
            {
                //fix: VisualTarget 的根 Visual 不能具有父级。
                _mainWindow.Activate();
                return;
            }
            if (config.General.IsSaveWindowSize)
            {
                _mainWindow.Width = config.General.WindowWidth;
                _mainWindow.Height = config.General.WindowHeight;
            }
            _mainWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            _mainWindow.WindowState = WindowState.Normal;
            _mainWindow.Show();
            _mainWindow.Activate();

            _uIServicer.InitWindow(_mainWindow);
            SetIcon(IconType.T1);
        }

        private void _mainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var window = sender as MainWindow;

            _themeServicer.SetMainWindow(window);
            _themeServicer.UpdateWindowStyle();
        }

        private void ExitApp()
        {
            hook_mouse.MouseUpEvent -= OnGlobalMouseUp;
            hook_mouse.UnHook();
            hook_mouse = null;
            _appObserver.Stop();

            HideMenu();
            _statusBarIcon.Visible = false;

            Application.Current.Shutdown();
        }
        private void ExitMenuItem_Click(object sender, RoutedEventArgs e)
        {
            ExitApp();
        }

        private void MainWindowMenuItem_Click(object sender, RoutedEventArgs e)
        {
            ShowMainWindow();
        }

        private void _statusBarIcon_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left && !AppState.IsLoading)
            {
                //双击托盘图标显示主窗口
                ShowMainWindow();
            }
        }

        private void _statusBarIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right && !AppState.IsLoading)
            {
                //右键单击弹出托盘菜单
                Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Send, new Action(ShowMenu));
            }
        }

        internal bool ok = false;
        internal void ShowMenu()
        {
            lock (this)
            {
                if (ok) return;
                ok = true;
            }
            try
            {
                _contextMenu.IsOpen = ok;
                _contextMenu.UpdateLayout();
                _contextMenu.BringIntoView();
            }
            catch
            {
                ok = false;
                Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Send, new Action(ShowMenu));
            }
        }

        internal void HideMenu()
        {
            lock (this)
            {
                if (!ok) return;
                ok = false;
            }
            _contextMenu.IsOpen = ok;
        }
    }
}
